package main
import (
	"fmt"
        "io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"strings"
        "log"
	"net"
	"net/http"
	"time"
)
var httpLog *log.Logger
var timout int
var RemoteUrl string
var SrsDir  string

//http short-connection 
func initHttps() *http.Client {
	client:=&http.Client{
                Transport :&http.Transport{
                        Dial: func(netw,addr string) (net.Conn,error) {
                                conn,err:=net.DialTimeout(netw,addr,time.Second*(time.Duration(timout)))
                                if err!=nil{
                                        return nil,err
                                }
                                conn.SetDeadline(time.Now().Add(time.Second*(time.Duration(timout))))
                                return conn,nil
                        },
                        ResponseHeaderTimeout: time.Second*(time.Duration(timout)),
                },
        }
	return client
}

//http long_connection
func initHttpl() *http.Client() {
	  client:=&http.Client{
                Transport :&http.Transport{
                        Dial: func(netw,addr string) (net.Conn,error) {
                                conn,err:=net.Dial(netw,addr)
                                if err!=nil{
                                        return nil,err
                                }
                                return conn,nil
                        },
                },
        }
        return client 
}
	
func putFile(filename string,newfilename string, client *http.Client) error {
	defer func() {
                if err:=recover();err!=nil {
                        httpLog.Println(err)
                }
        }()
	file,err:=os.OpenFile(filename,os.O_RDWR,0)
	defer file.Close()
	if err!=nil {
		return err
	}
	fmt.Printf("transcode_upload: local_file  == %s\n",filename)
	fmt.Printf("transcode_upload: remote_file == %s\n",RemoteUrl+"/"+newfilename) 
	reqest,err:=http.NewRequest("PUT",RemoteUrl+"/"+newfilename,file)
	if err!=nil {
		httpLog.Println(err)
		return err
	}
	reqest.Header.Set("Conntection","keep-alive")
	resp,err:=client.Do(reqest)
	if err!=nil  {
		httpLog.Println(err)
		return err
	}
	fmt.Printf("HTTP PUT request success: [%s]\n",RemoteUrl+"/"+newfilename)
	defer resp.Body.Close()
	resp_body,err:=ioutil.ReadAll(resp.Body)
	if err!=nil {
		return err
	}
	httpLog.Printf(string(resp_body))
	httpLog.Printf("End to putFile for %s.",filename)
	return nil
}
/*
func checkNewTs(SrsDir string,isNewFileExist chan int,bufc *bytes.Buffer) {
	for {	
		bufc.Reset()
                bsh := fmt.Sprintf("ls  %s/*.ts|wc -l",SrsDir)
                cmd := exec.Command("/bin/bash", "-c", bsh)
                cmd.Stdout = bufc
                cmd.Stderr = bufc
                cmd.Run()
                tsNum:=strings.Replace(bufc.String(), "\n", "", -1)
		if tsNum=="2" {
			timer1:=time.NewTicker(time.Duration(50)*time.Millisecond)
                        select {
                                case <-timer1.C:
                                        break
                                case isNewFileExist<-1:
                                        break
			}
			break
		}
	}
}
*/

func main() {
	defer func() {
                if err:=recover();err!=nil {
                        httpLog.Println(err)
                }
        }()
        logFile, err := os.Create("./upload.log")
        defer logFile.Close()
        if err != nil {
                fmt.Printf("Open file error!\n")
        }
	httpLog= log.New(logFile, "[Info]", log.Ldate|log.Ltime|log.Lshortfile)
	httpLog.Printf("ok!\n")
	arg_num :=len(os.Args)
	if arg_num!=4 {
		httpLog.Printf("arg_num is %d.\n",arg_num)
		return
	}
	timout,err=strconv.Atoi(os.Args[1])
	if err!=nil{
		httpLog.Println(err)
		return
	}	
	RemoteUrl=os.Args[2]
	SrsDir=os.Args[3]
	fmt.Printf("transcode_upload: remote_dir == %s\n",RemoteUrl)
	fmt.Printf("transcode_upload: local_dir  == %s\n",SrsDir)
	var loopcnt int=0
	client:=initHttpl()
	for {
		var tsFileName,filename,m3u8File string
		var isTsFileExist bool=true
		var isM3U8Exist   bool=false
		file_list,err:=ioutil.ReadDir(SrsDir)
                if err!=nil {
                        fmt.Println(err)
                        continue
                }
                for _,tmpfile:= range file_list {
                        tmpfilename:=tmpfile.Name()
                        if filepath.Ext(tmpfilename) == ".m3u8" {
                                m3u8File=tmpfilename
				isM3U8Exist=true
                                httpLog.Println(m3u8File)
                                break
                        }
                }
		if isM3U8Exist==false {
			fmt.Printf("m3u8 file not exist!\n")
			continue
		}
		file_content,err:=ioutil.ReadFile(SrsDir+"/"+m3u8File)
		if err!=nil {
			fmt.Println(err)
			continue
		}
		s:=strings.Split(string(file_content),"\n")
		if len(s)<2 {
			fmt.Printf("Wrong format for m3u8 file!\n")
			continue
		}
		filename=s[len(s)-2]
		tsFileName=SrsDir+"/"+filename
		if _,err:=os.Stat(tsFileName);err!=nil {
			if os.IsNotExist(err) {
				isTsFileExist=false
			}
		}
		if isTsFileExist {
                	httpLog.Printf("tsFileName is %s,and filename is %s.\n",tsFileName,filename)
			err:=putFile(tsFileName,filename,client)
			if err!=nil {
				fmt.Println(err)
				loopcnt=loopcnt+1
				if loopcnt==5 {
					loopcnt=0
					err:=os.Remove(tsFileName)
					if err!=nil {
						fmt.Println(err)
					}
					
				}
				continue
			}
			httpLog.Printf("putFile %s success!\n",filename)
                        err=putFile(SrsDir+"/"+m3u8File,"index.m3u8",client)
                        if err!=nil {
                        	fmt.Println(err)
				continue
                        }
			err=os.Remove(tsFileName)
                        if err!=nil {
                        	fmt.Println(err)
                                continue
                        } 
                        httpLog.Printf("Remove file %s success!\n",tsFileName)
        	}
	}
}						
					
















								
				
	
